﻿using Microsoft.Extensions.Options;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Ding.MongoDB
{
    public class MongoDbContext: IMongoDbContext
    {
        /// <summary>
        /// 数据库对象
        /// </summary>
        public IMongoDatabase Database { get; } = null;

        /// <summary>
        /// 实例化
        /// </summary>
        /// <param name="options"></param>
        public MongoDbContext(IOptions<MongoDBOptions> options)
        {
            var client = new MongoClient(options.Value.ConnectionString);
            if (client != null)
            {
                Database = client.GetDatabase(options.Value.DataBase);
            }
        }

        /// <summary>
        /// 根据查询条件，获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="conditions"></param>
        /// <returns></returns>
        public List<T> GetList<T>(Expression<Func<T,bool>> conditions = null)
        {
            var collection = Database.GetCollection<T>(typeof(T).Name);
            if (conditions != null)
            {
                return collection.Find(conditions).ToList();
            }
            return collection.Find(_ => true).ToList();
        }

        /// <summary>
        /// 根据查询条件，获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="conditions"></param>
        /// <returns></returns>
        public async Task<List<T>> GetListAsync<T>(Expression<Func<T, bool>> conditions = null)
        {
            var collection = Database.GetCollection<T>(typeof(T).Name);

            if (conditions != null)
            {
                return (await collection.FindAsync(conditions)).ToList();
            }
            return (await collection.FindAsync(_ => true)).ToList();
        }

        /// <summary>
        /// 插入单条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public T InsertOne<T>(T model)
        {
            var collection = Database.GetCollection<T>(typeof(T).Name);
            collection.InsertOne(model);
            return model;
        }

        /// <summary>
        /// 插入单条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<T> InsertOneAsync<T>(T model)
        {
            var collection = Database.GetCollection<T>(typeof(T).Name);
            await collection.InsertOneAsync(model);
            return model;
        }

        /// <summary>
        /// 插入多条数据，数据用list表示
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public List<T> InsertMay<T>(List<T> list)
        {
            var collection = Database.GetCollection<T>(typeof(T).Name);
            collection.InsertMany(list);
            return list;
        }

        /// <summary>
        /// 插入多条数据，数据用list表示
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public async Task<List<T>> InsertMayAsync<T>(List<T> list)
        {
            var collection = Database.GetCollection<T>(typeof(T).Name);
            await collection.InsertManyAsync(list);
            return list;
        }
    }
}
